using System;
using System.Collections;
using UnityEngine;

namespace VoxelEngine.Utils
{
	[Serializable]
	public class PoolDescription
	{
		[SerializeField]
		private GameObject _prefab;

		[SerializeField]
		private int _poolSize;

		[SerializeField]
		private bool _growable;

		public GameObject Prefab
		{
			get
			{
				return _prefab;
			}
			set
			{
				_prefab = value;
			}
		}

		public int PoolSize
		{
			get
			{
				return _poolSize;
			}
			set
			{
				_poolSize = value;
			}
		}

		public bool Growable
		{
			get
			{
				return _growable;
			}
			set
			{
				_growable = value;
			}
		}

		private GameObject[] Pool
		{
			get;
			set;
		}

		private int DenyUntilFrame
		{
			get;
			set;
		}

		private int Iterator
		{
			get;
			set;
		}

		private DynamicObjectPool Owner
		{
			get;
			set;
		}

		public void Initialize(DynamicObjectPool owner)
		{
			Owner = owner;
			Pool = new GameObject[PoolSize];
			owner.StartCoroutine(InitializePoolAsync());
		}

		private IEnumerator InitializePoolAsync()
		{
			for (int i = 0; i < PoolSize; i++)
			{
				Pool[i] = Instantiate(i);
				if (PoolSize % 5 == 0)
				{
					yield return null;
				}
			}
		}

		public void GrowUp()
		{
			int num = PoolSize + 1;
			GameObject[] array = new GameObject[num];
			for (int i = 0; i < PoolSize; i++)
			{
				array[i] = Pool[i];
			}
			for (int j = PoolSize; j < num; j++)
			{
				array[j] = Instantiate(j);
			}
			PoolSize = num;
			Pool = array;
		}

		private GameObject Instantiate(int index)
		{
			GameObject gameObject = UnityEngine.Object.Instantiate(Prefab);
			gameObject.transform.SetParentAndKeepScale(Owner.transform);
			gameObject.SetActive(value: false);
			gameObject.name = gameObject.name + " " + index.ToString("0000");
			return gameObject;
		}

		public GameObject Create(string name, Vector3 position)
		{
			if (DenyUntilFrame > Owner.frame)
			{
				return null;
			}
			for (int i = 0; i < Pool.Length; i++)
			{
				int num = (Iterator + i) % Pool.Length;
				GameObject gameObject = Pool[num];
				if (gameObject != null && !gameObject.activeSelf)
				{
					gameObject.transform.position = position;
					gameObject.SetActive(value: true);
					Iterator = (num + 1) % Pool.Length;
					return gameObject;
				}
			}
			if (Growable)
			{
				GrowUp();
				return Create(name, position);
			}
			DenyUntilFrame = Owner.frame + 30;
			return null;
		}
	}
}
